הדור הבא של המנוע המפורסם שוחרר,למד מהם השינויים והחידושים שהגיעו לשפה.
עברה יותר משנה מאז שהוכרזה הגירסא הבאה של PHP במהלך השנה הזו קויימו דיונים רבים לגבי החידושים שהיא אמורה להביא.
הגירסא שוחחרה בתאריך 3 בדצמבר 2015,במאמר זה נכיר את הדברים החדשים שנוספו לשפה אז בואו נתחיל.
ביצועים ביצועים ועוד קצת ביצועים
מה שהיה ידוע כבר לפני שנה הוכח ברגע שיצאה הגירסא הראשונה - המנוע החדש הוא המהיר ביותר שפותח עד היום.המנוע החדש מהיר עד כ- פי 2 מהמנוע הנוכחי [5.6] בלי לשנות אפילו שורה אחת של קוד וזאת תודות בעיקר ל PHPNG.
The null coalescing operator
כולנו מכירים את החלק הזה שאנחנו צריכים לבדוק האם המשתנה מוגדר לפני שמשתמשים בו,פעולה שמרגישה קצת העתק-הדבק.
כעט הקוד -
$slug = isset($_GET['slug']) ? $_GET['slug'] : '';
יכול להפוך ל -
$slug = $_GET['slug'] ?? '';
Combined Comparison AKA Spaceship Operator
עוד אופרטור חדש שנכנס למנוע הוא האופרטור "חללית" בשל צורתו שמזכירה ציור של חללית.
הקוד -
$id <=> $second_id
יכול להחזיר לנו שלושה מספרים 1 [אחד] ,0 [אפס] ,-1 [מינוס אחד] ויכול לעזור לנו כאשר אנו רוצים לבדוק שוויון בין שני משתנים.
-1 [מינוס אחד] יוחזר כאשר id קטן מ- second_id.
0 [אפס] יוחזר כאשר שני המשתנים שווים אחד לשני.
1 [אחד] יוחזר מתי ש id גדול מ second_id.
משתנים סקלרים
כבר הרבה זמן שאנחנו יכולים להגדיר לפונקציה לקבל רק interface מסויים או רק אוביקט מסויים.
החל מ php 7 יהיה ניתן להגדיר פונקציה שתקבל כל משתנה סקלארי.
כלומר מהיום נוכל להגדיר תנאי כניסה לפונקציה הוא שהשמתנה חייב להיות מספר שלם ולתת למנוע לבדוק עבורנו אם הוא מספר.
לדוגמא אם בעבר היינו צריכים לכתוב משהו כזה -
public function setID($id){
if(!is_int($id))
throw new Exception();
$this->id = $id;
return $this;
}
if(!is_int($id))
throw new Exception();
$this->id = $id;
return $this;
}
היום נוכל לכתוב
public function setID(int $id){
$this->id = $id;
return $this;
}
$this->id = $id;
return $this;
}
והמנוע כבר יזרוק עבורנו את השגיאה TypeException.
החזרת טיפוס מפונקציה
שינוי נוסף במבנה של הפונקציה מאפשר לנו היום לדרוש מפונקציה להחזיר טיפוס מסויים.
לדוגמא אם אנחנו יודעים שפונקציה מסויימת חייבת להחזיר לנו int נכתוב אותה כך -
function ReturnINT() : int {
}
}
גם כאן,במידה ולא נחזיר את הטיפוס שהגדרנו תזרק השגיאה TypeException.
החיסרון הוא שניתן להחזיר רק טיפוס אחד כך שאם יש פונקציה שיכולה להחזיר int או false לא נוכל להגדיר את הפונקציה כמו שצריך ונצטרך להשאיר אותה במתכונת הישנה.
Group use Declarations
שינוי שיקל עוד טיפה בכתיבה שלנו היא אפשרות להכליל מספר נתיבים תחת "use" אחד.
כך שהקוד -
use App\ClassA;
use App\ClassB;
use App\ClassB;
יכול להיכתב גם כך -
use App\{ClassA, ClassB};
אני אישית עדיין לא סגור כמה הכתיבה הזאת נוחה אבל אין ספק בכלל שהפתרון יותר טוב מאשר לבצע העתק-הדבק כאשר מדובר בהרבה תת - namespace-ים
אגב השינוי הוא כללי למילה "use" באותה מידה שהוא טופס על מחלקות הוא טופס גם עבור ממשקים,פונקציות וקבועים.
מחלקה אנונימית
סוג של הגדרת מחלקה in-line,כתיבה קצת מסוכנת ,הייתי מגדיר כאן כלל לשימוש - רק למחלקות שצריכות להיות מוגדרות פעם אחת וגם אז לשים אולי סינון כל שהוא.
var_dump(new class($i) {
public function __construct($i) {
$this->i = $i;
}
});
public function __construct($i) {
$this->i = $i;
}
});
שינויים בהתמודדות עם שגיאות
אם בעבר היה נורא קשה לתפוס שגיאות שקורות בעקבות שגיאות בקוד עצמו כמו לשכוח נקודה פסיק בסוף משפט או יציאה מגבולות המערך השינוי הוסיף המון סוגים חדשים של שגיאות שמקל עלינו את ההתמודדות מול אותם שגיאות.
אם בעבר ההגדרה הכללית עבור שגיאה עבורנו הייתה המחלקה "Exception" היום כל שגיאה מוגדרת ע"י הממשק "Throwable" כך שאם נרצה לתפוס כל שגיאה אפשרית נבצע זאת כך -
try {
//Some code goes here
} catch (Throwable $t) {
// Handle exception
}
//Some code goes here
} catch (Throwable $t) {
// Handle exception
}
המבנה החדש נראה כך -
\Throwable
├── \Exception (implements \Throwable)
│ ├── \LogicException (extends \Exception)
│ │ ├── \BadFunctionCallException (extends \LogicException)
│ │ │ └── \BadMethodCallException (extends \BadFunctionCallException)
│ │ ├── \DomainException (extends \LogicException)
│ │ ├── \InvalidArgumentException (extends \LogicException)
│ │ ├── \LengthException (extends \LogicException)
│ │ └── \OutOfRangeException (extends \LogicException)
│ └── \RuntimeException (extends \Exception)
│ ├── \OutOfBoundsException (extends \RuntimeException)
│ ├── \OverflowException (extends \RuntimeException)
│ ├── \RangeException (extends \RuntimeException)
│ ├── \UnderflowException (extends \RuntimeException)
│ └── \UnexpectedValueException (extends \RuntimeException)
└── \Error (implements \Throwable)
├── \AssertionError (extends \Error)
├── \ParseError (extends \Error)
└── \TypeError (extends \Error)
├── \Exception (implements \Throwable)
│ ├── \LogicException (extends \Exception)
│ │ ├── \BadFunctionCallException (extends \LogicException)
│ │ │ └── \BadMethodCallException (extends \BadFunctionCallException)
│ │ ├── \DomainException (extends \LogicException)
│ │ ├── \InvalidArgumentException (extends \LogicException)
│ │ ├── \LengthException (extends \LogicException)
│ │ └── \OutOfRangeException (extends \LogicException)
│ └── \RuntimeException (extends \Exception)
│ ├── \OutOfBoundsException (extends \RuntimeException)
│ ├── \OverflowException (extends \RuntimeException)
│ ├── \RangeException (extends \RuntimeException)
│ ├── \UnderflowException (extends \RuntimeException)
│ └── \UnexpectedValueException (extends \RuntimeException)
└── \Error (implements \Throwable)
├── \AssertionError (extends \Error)
├── \ParseError (extends \Error)
└── \TypeError (extends \Error)
המבנה נלקח מ DAVEY SHAFIK
כפי שניתן לראות נוספו המון שגיאות חדשות בין היתר TypeError שכבר הראינו למעלה מקרים בהם הוא נזרק.
את Throwable לא נוכל לממש במחלקה משלנו,מדובר בממשק סגור עבור Exception ו Error,על מנת ליצור חריג משלנו נצטרך להחליט האם מדובר ב"שגיאה" או "חריג".
השינוי לא אמור להשפיע על מערכות קיימות מאחר והשגיאות שמגיעות מהמנוע לא ממשות את Exception אלה את Error.
תוספות ל Generators
שתי פיצ'רים חדשים שנוספו לפונקציות מסוג זה -
1.שימוש ב return
החל מ php 7 יהיה ניתן להחזיר ערך מפונקציית generator,בגירסאות ישנות יותר הדבר יזרוק שגיאה.
את הערך שהוחזר ניתן לקבל ע"י שימוש במתודה getReturn ניתן להשתמש בפונקציה רק כאשר הפונקציה החזירה ערך במידה וננסה להשתמש בפונקציה getReturn תוך כדי שהפונקציית generator עדיין מחזירה ערכים מ yield נקבל שגיאה.
2.Generator Delegation
הפיצ'ר מאפשר לנו לקרוא מפונקציית generator למבנה אחר שמממש את הממשק iterable כלומר - מערך ,iterator או פונקציית generator אחרת.
דוגמא שממשת את שתי האפשרויות החדשות -
<?php
function g1() {
yield 2;
yield 3;
return 42;
}
function g2() {
yield 1;
$g1result = yield from g1();
yield 4;
return $g1result;
}
$g = g2();
foreach ($g as $yielded) {
var_dump($yielded);
}
var_dump($g->getReturn());
/*
int(1)
int(2)
int(3)
int(4)
int(42)
*/
function g1() {
yield 2;
yield 3;
return 42;
}
function g2() {
yield 1;
$g1result = yield from g1();
yield 4;
return $g1result;
}
$g = g2();
foreach ($g as $yielded) {
var_dump($yielded);
}
var_dump($g->getReturn());
/*
int(1)
int(2)
int(3)
int(4)
int(42)
*/
נלקח מה-RFC
מפרש משמאל לימין
החל מהגירסאות החדשות של PHP המנוע ינסה לפרש כמה שהוא יכול משמאל לימין כלומר אם הקוד -
$$foo['bar']['baz']
בעבר היה מפורש כ -
${$foo['bar']['baz']}
החל מ php 7 הוא יפורש כך -
($$foo)['bar']['baz']
כך שהוא קודם מקבל את הערך של foo לדוגמא A ואז משתמש במערך A ומחפש בתוכו את ['bar']['baz]
גם הקוד -
$foo->$bar['baz']
שבעבר היה מפורש כך -
$foo->{$bar['baz']}
מפורש כעט כך -
($foo->$bar)['baz']
כמובן שלא ניתן לסקר את כל האפשרויות החדשות שנוספו לשפה אך אלה ללא ספק "הגדולים ביותר" מידע נוסף על כל השינויים שקרו ניתן למצוא בקובץ UPGRADING
תגובות לכתבה:
מגניב, תודה :)
תודה :)
יפה מאד, אתר מדהים
שוחררה RC 4
תודה על העדכון :)
תוכל להרחיב עלPHPNG בבקשה?
כמו כן למה יש צורך אחרי בדיקת$_GET['slug'] לאפס אותו לריק?(הדוגמה הראשונה)
@MYSQL
אין לי באמת מקום לכתוב על PHPNG ,אפשר לכתוב עליו מאמר שלם ולבצע השוואות בינו לבין HHVM אבל אין לי זמן לזה כרגע,אתה מוזמן לקרוא באינטרנט ,לתרגם ולפרסם פה.
לגבי הקוד,לשום קוד פה אין באמת משמעות,בסך הכל דוגמאות שמראות את האפשרויות החדשות יש מקרים רבים שאתה לא יכול להסיק שהמשתנה באמת קיים ואתה תצטרך לבצע isset לפני שתעשה עליו פעולות,באותם מקרים אתה עלול לרצות שגם אם הערך לא קיים אז שיהיה לו ערך ברירת מחדל כמו למשל במקרה של עמודים,אם אתה לא מקבל את $_GET['page'] אתה רוצה שהערך ברירת מחדל שלו יהיה 1 אז במקום לבצע תנאי isset אתה יכול להשתמש בכיתוב המקוצר.
שוחררה RC 7 ותאריך השחרור נדחה ל 26 בנובמבר (12 בנובמבר במקור) בהנחה שלא יהיו באגים קריטים היא תשוחרר בתאריך הנ"ל,אחרת תצא RC 8 והשחרור ידחה ל 10 בדצמבר.(וחוזר חלילה עד אשר הגירסא תיהיה יציבה מספיק)
מגניב ביותר. תודה על העדכונים השותפים